<div id="downloadBtn">123</div>

<script>
	/*
 * @Description:
 * @Author: dh
 * @Date: 2022-07-14 15:47:45
 * @LastEditors: dh
 * @LastEditTime: 2023-08-21 10:50:57
 */
	/**
	 * @key: Blob
	 * @introduce https://mp.weixin.qq.com/s?__biz=MzI2MjcxNTQ0Nw==&mid=2247484522&idx=1&sn=7028aa65a4dec0f2d0cb847838703bc3&scene=21#wechat_redirect
	 * @description:表示二进制类型的大对象，通常是影像、声音或多媒体文件，读取后不可更改。 通常用来读写文件，
	 * @param {blobParts} 文件、图像、视频、音频、字符串、DOMStrings 、ArrayBuffer、Uint8Array 或者一个其他 Blob ，组成的数组
	 * @param {options} 可选，其中 type 通常为 MIME 类型 ，表示 Blob 的文件类型。
	 * @return {*} blob对象
	 */

	// TODO 基本用法
	// new Blob(blobParts, options); 表示一个二进制数据对象，不可更改
	var blob = new Blob(['Hello World'], { type: 'text/plain' })
	var blob = new Blob(['<a id="a"><b id="b">hey!</b></a>'], { type: 'text/html' }) // 实例对象blob包含的是字符串。生成实例的时候，数据类型指定为text/html
	var blob = new Blob([JSON.stringify({ hello: 'world' })], { type: 'application/json' }) // Blob 保存 JSON 数据

	console.log('==========================================================================================')

	// TODO 属性

	// 象含有两个属性：size 和 type。
	// size 属性用于表示数据的大小（以字节为单位）
	// type 一个字符串，表明该 Blob 对象所包含数据的 MIME 类型。如果类型未知，则该值为空字符串

	console.log('==========================================================================================')

	// TODO 方法

	// slice([start[, end[, contentType]]])：返回一个新的 Blob 对象，包含了源 Blob 对象中指定范围内的数据。
	// stream()：返回一个能读取 blob 内容的 ReadableStream。
	// text()：返回一个 Promise 对象且包含 blob 所有内容的 UTF-8 格式的 USVString。
	// arrayBuffer()：返回一个 Promise 对象且包含 blob 所有内容的二进制格式的 ArrayBuffer。

	console.log('==========================================================================================')

	// TODO 使用场景

	// 1.分片上传
	const file = new File(['a'.repeat(1000000)], 'test.txt', { type: 'text/plain' })
	const chunkSize = 40000 // 每个分片字节数
	async function chunkedUpload() {
		for (let start = 0; start < file.size; start += chunkSize) {
			// chunk 就是 blob数据
			const chunk = file.slice(start, start + chunkSize + 1)
			const fd = new FormData()
			fd.append('data', chunk)
			await fetch('https://httpbin.org/post', { method: 'post', body: fd }).then(res => res.text())
		}
	}

	// 2.从互联网下载数据
	const downloadBlob = (url, callback) => {
		const xhr = new XMLHttpRequest()
		xhr.open('GET', url)
		xhr.responseType = 'blob'
		xhr.onload = () => {
			callback(xhr.response)
		}
		xhr.send(null)
	}

	// 3.获取线上图片并本地显示
	const myImage = document.querySelector('img')
	const myRequest = new Request('flowers.jpg')

	fetch(myRequest)
		.then(function (response) {
			return response.blob()
		})
		.then(function (myBlob) {
			let objectURL = URL.createObjectURL(myBlob)
			myImage.src = objectURL
		})

	console.log('==========================================================================================')

	// TODO Blob 用作 URL 可以通过 URL.createObjectURL 方法来创建 Blob URL，
	// Blob URL 就是普通 URL，因此可以下载。该方法接收一个 Blob 对象，并为其创建一个唯一的 URL，其形式为 blob:<origin>/<uuid>，对应的示例如下：
	// Content-Disposition 中指定的 download 属性优先级高于 a.download
	// 文件下载
	const download = (fileName, blob) => {
		const link = document.createElement('a')
		link.href = URL.createObjectURL(blob)
		link.download = fileName
		link.click()
		link.remove()
		URL.revokeObjectURL(link.href)
	}

	const downloadBtn = document.querySelector('#downloadBtn')
	downloadBtn.addEventListener('click', event => {
		const fileName = 'blob.txt'
		const myBlob = new Blob(['一文彻底掌握 Blob Web API'], { type: 'text/plain' })
		download(fileName, myBlob)
	})

	console.log('==========================================================================================')

</script>